<?php

namespace app\common\traits;

use app\common\library\exception\ApiException;
use think\Exception;
use think\Validate;

trait ControllerCheckValidate
{

    /**
     * 检测用户输入参数
     * @param $validate
     * @param $params
     * @return bool
     * @throws ApiException
     */
    protected function apiValidate($validate, $params): bool
    {
        /** @var Validate $validate */
        $result = $validate->check($params);
        if ($result != true) {
            throw new ApiException($validate->getError(), 400);
        }

        return true;
    }

    /**
     * 获取控制器验证类
     * @return string
     */
    protected function getControllerValidate(): string
    {
        $divArr   = explode('\\', static::class);
        $name     = array_pop($divArr);
        $divArr[] = 'validate';
        $divArr[] = $name . 'Validate';
        return implode('\\', $divArr);
    }

    /**
     * 检查验证
     * @param Validate $validate
     * @param string $function
     * @return bool
     */
    private function checkValidate(Validate $validate, string $function = 'apiValidate'): bool
    {
        $action = request()->action(true);
        $validate->scene($action);
        if (!$validate->hasScene($action)) {
            $sceneFunction = "scene" . ucfirst($action);
            if (method_exists($validate, $sceneFunction)) {
                $validate->scene($action, $validate->$sceneFunction());
            } else {
                return true;
            }
        }
        $params = request()->param();
        return $this->$function($validate, $params);
    }

    /**
     * 执行验证
     * @return void
     */
    protected function validateRun(): void
    {
        $validateName = $this->getControllerValidate();
        if (class_exists($validateName) && !$this->checkValidate(new $validateName())) {
            $this->response(false)->send();
            exit;
        }
    }
}